// 采用 ES2015(ES6) 提供的 class 实现继承

// 在 ES6 可以使用 class 关键字来声明"类"
class Animal {
    // 在类体括号内部可以使用 constructor 声明构造函数
    constructor(id, name) {
            // 在构造函数内部通过 this 绑定实例属性
            this.id = id;
            this.name = name;
        }
        // 可以在类体括号内直接声明实例函数
    introduce() {
        console.log(this.id, this.name);
    }
}

class Birds extends Animal {
    constructor(id, name) {
        // 子类构造函数中可以通过 super 来调用父类的构造函数
        super(id, name);
    }
}

class Beast extends Animal {
    constructor(id, name) {
        // 子类构造函数中可以通过 super 来调用父类的构造函数
        super(id, name);
    }
}

let birds = new Birds(1, '孔雀');
console.log(birds);

console.log(birds.__proto__); //实例对象Birds的原型
console.log(birds.__proto__ === Birds.prototype); // true

console.log(birds.__proto__.__proto__);
console.log(birds.__proto__.__proto__ === Animal.prototype); // true

console.log(birds.__proto__.__proto__.__proto__);
console.log(birds.__proto__.__proto__.__proto__ === Object.prototype); // true

console.log('- - - - - - - - - - - - - - - -');

function Shape(name) {
    this.name = name;
}

function Triangle(a, b, c) {
    this.first = a;
    this.second = b;
    this.third = c;
}

// 1、将 子对象(class-level) 的原型修改为 父对象(class-level) 的 实例(instance)
//    将 Triangle 的 原型 修改为 Shape 的实例
Triangle.prototype = new Shape('三角形'); // 请注意，父对象的实例是我们自己创建的
// 2、将 子对象(class-level)原型 的 constructor 属性值修改为 子对象(class-level)对应的构造函数
Triangle.prototype.constructor = Triangle;

let t = new Triangle(30, 40, 50);
console.log(t.name);
console.log(t);

console.log(t.__proto__);
console.log(t.__proto__ === Triangle.prototype); // true

console.log(t.__proto__.__proto__);
console.log(t.__proto__.__proto__ === Shape.prototype); // true

console.log(t.__proto__.__proto__.__proto__);
console.log(t.__proto__.__proto__.__proto__ === Object.prototype); // true

let r = new Triangle(60, 60, 60);
console.log(r.name); // Triangle.prototype.name
console.log(r);

console.log(r.hasOwnProperty('name')); // false

r.name = '仨角形'; // 在 r 所指向的实例中新增了一个 name 属性
console.log(r.name);
console.log(r.hasOwnProperty('name')); // true